import pandas as pd

def calc_woe_iv(df, var_list, target):
    dict_out = {}
    
    # loop all variables
    for var in var_list: 
        print('{0} {1} {0}'.format('*'*int((48-len(var))/2), var))
        dict_out[var] = {}
        
        # calculate woe of each variable
        print('calculating WOE of {} ...'.format(var))
        group_woe = df.sort_values(var).groupby(var)[target]

        df_woe = group_woe.count().to_frame('总计').reset_index()
        df_woe_target = group_woe.value_counts().to_frame().unstack().reset_index()
        df_woe = pd.merge(df_woe, df_woe_target, on=var, how='left')
        
        df_woe['good%'] = df_woe[(target, 1)]/df_woe['总计']
        df_woe['bad%'] = df_woe[(target, 0)]/df_woe['总计']
        df_woe['woe'] = np.log(df_woe['bad%']/df_woe['good%'])
        
        dict_out[var]['WOE'] = df_woe

        # calculate iv of each variable
        print('calculating IV of {} ...'.format(var))
        df_iv = df_woe.copy()
        df_iv['iv'] = (df_iv['bad%'] - df_iv['good%']) * df_iv['woe']
        dict_out[var]['IV'] = df_iv
        
        print('*'*50)
        
    return dict_out